using UnityEngine;
using UnityEngine.EventSystems;

public class LimitUIDrag : MonoBehaviour, IBeginDragHandler, IDragHandler
{
    [Header("表示限制的区域")]
    public RectTransform LimitContainer;
    [Header("场景中Canvas，需要修改获取方式")]
    public Canvas canvas;
    [Header("可以拖动的UI区域")]
    public RectTransform rt;
    // 位置偏移量
    Vector3 offset = Vector3.zero;
    // 最小、最大X、Y坐标
    float minX, maxX, minY, maxY;

    void Start()
    {
        canvas = transform.GetComponentInParent<Canvas>();
    }

    /// <param name="eventData"></param>
    public void OnBeginDrag(PointerEventData eventData)
    {
        if (eventData.button != PointerEventData.InputButton.Left)
            return;
        if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.enterEventCamera, out Vector3 pos))
        {
            offset = rt.position - pos;

            SetDragRange(eventData.enterEventCamera);
        }
    }

    /// <param name="eventData"></param>
    public void OnDrag(PointerEventData eventData)
    {
        if (eventData.button != PointerEventData.InputButton.Left)
            return;

        if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.pressEventCamera, out Vector3 pos))
        {
            rt.position = DragRangeLimit(pos + offset);
        }
    }


    /// <summary>
    /// 设置最大、最小坐标
    /// </summary>
    void SetDragRange(Camera camera)
    {
        var screen_pos = RectTransformUtility.WorldToScreenPoint(camera, LimitContainer.position);

        minX = screen_pos.x
            - LimitContainer.pivot.x * LimitContainer.rect.width * canvas.scaleFactor
            + rt.rect.width * canvas.scaleFactor * rt.pivot.x;

        maxX = screen_pos.x
            + (1 - LimitContainer.pivot.x) * LimitContainer.rect.width * canvas.scaleFactor
            - rt.rect.width * canvas.scaleFactor * (1 - rt.pivot.x);

        minY = screen_pos.y
            - LimitContainer.pivot.y * LimitContainer.rect.height * canvas.scaleFactor
            + rt.rect.height * canvas.scaleFactor * rt.pivot.y;

        maxY = screen_pos.y
            + (1 - LimitContainer.pivot.y) * LimitContainer.rect.height * canvas.scaleFactor
            - rt.rect.height * canvas.scaleFactor * (1 - rt.pivot.y);

        RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, new Vector2(minX, minY), camera, out Vector3 min_pos);
        RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, new Vector2(maxX, maxY), camera, out Vector3 max_pos);

        minX = min_pos.x;
        minY = min_pos.y;

        maxX = max_pos.x;
        maxY = max_pos.y;
    }

    /// <summary>
    /// 限制坐标范围
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    Vector3 DragRangeLimit(Vector3 pos)
    {
        pos.x = Mathf.Clamp(pos.x, minX, maxX);
        pos.y = Mathf.Clamp(pos.y, minY, maxY);
        return pos;
    }
}

